﻿//
//
// 版权所有 (c) 2021-2023 JR  
//
// 特此免费授予获得本软件的任何人以处理本软件的权利，但须遵守以下条件：在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
//
// 软件按“原样”提供，不提供任何形式的明示或暗示的保证，包括但不限于对适销性、适用性和非侵权的保证。
// 在任何情况下，作者或版权持有人均不对任何索赔、损害或其他责任负责，无论是因合同、侵权或其他方式引起的，与软件或其使用或其他交易有关。

using Furion.Core;
using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EMC.VISITOR.Core;
public static class RabbitMqSetUp
{
    public static void AddRabbitMqByEventBus(this IServiceCollection service)
    {
        var rabbitMqOptions = App.GetOptions<RabbitMqOptions>();
        try
        {
            service.AddEventBus(options =>
            {
                var factory = new ConnectionFactory
                {
                    HostName = rabbitMqOptions.Host,
                    UserName = rabbitMqOptions.Name,
                    Password = rabbitMqOptions.Password,
                    Port = rabbitMqOptions.Port
                };
                options.UseUtcTimestamp = false;
                // 不启用事件日志
                options.LogEnabled = true;

                // 事件执行器（失败重试）
                options.AddExecutor<RetryEventHandlerExecutor>();
                //监视所有订阅事件，包括 执行之前、执行之后，执行异常，共享上下文数据
                options.AddMonitor<MyEventHandlerMonitor>();
                // 创建默认内存通道事件源对象，可自定义队列路由key，比如这里是 eventbus
                var rbmqEventSourceStorer = new RabbitMQEventSourceStorer(factory, rabbitMqOptions.Author, 3000);

                //订阅 EventBus 意外未捕获异常
                options.UnobservedTaskExceptionHandler =(obj, args) => {
                    //TODO
                };
                // 替换默认事件总线存储器
                options.ReplaceStorer(serviceProvider =>
                {
                    return rbmqEventSourceStorer;
                });
            });
        }
        catch (Exception ex)
        {
            AddLocalEventBus(service);
        }
    }

    /// <summary>
    /// 事件总线，本地事件源或Redis事件源
    /// </summary>
    /// <param name="service"></param>
    public static void AddLocalEventBus(this IServiceCollection service)
    {
        // 事件总线
        service.AddEventBus(options =>
        {
            options.UseUtcTimestamp = false;
            // 不启用事件日志
            options.LogEnabled = false;
            // 事件执行器（失败重试）
            options.AddExecutor<RetryEventHandlerExecutor>();
            options.AddMonitor<MyEventHandlerMonitor>();
            //// 替换事件源存储器
            //options.ReplaceStorer(serviceProvider =>
            //{
            //    var redisCache = serviceProvider.GetService<ICache>();
            //    // 创建默认内存通道事件源对象，可自定义队列路由key，比如这里是 eventbus
            //    return new RedisEventSourceStorer(redisCache, "eventbus", 3000);
            //});
        });
    }
}
